洛谷题解 P5019 【铺设道路】

思路一:

一看题就知道是模拟题,直接模拟每层填土的过程。

如图所示,一共需填9次土,可以直接用for语句循环判断需填土区块的数量。

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<iostream>
#include<cstdio>
int n,maxn=0,ans=0;
int h[100000]={0};
int max(int x,int y)
{
if(x>y)
{
return x;
}
else
{
return y;
}
}

int main()
{
scanf("%d",&n);
for(int a=1;a<=n;a++)
{
scanf("%d",&h[a]);
maxn=max(h[a],maxn);
}
for(int a=1;a<=maxn;a++)
{
for(int b=1;b<=n+1;b++)
{
if(h[b]<a&&h[b-1]>=a)
{
ans++;
}
}
}
printf("%d",ans);
return 0;
}

可惜这种方法只能拿80分的点,其他TLE。

思路2:

画图后发现,相邻的两部分所需填土的步数等于较高一部分的深度值(图中即3步)

若部分1深度>部分2深度,就有步数=部分1深度

若部分2深度>部分1深度,就有步数=部分2深度

所以不难推出(部分0深度=0):

当当前部分深度<前一部分深度,总步数不变

当当前部分深度>前一部分深度,总步数=总步数+当前部分深度-前一部分深度

代码实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include<iostream>
#include<cstdio>
using namespace std;
int n,ans=0,l=0;
int main()
{
scanf("%d",&n);
for(int a=1;a<=n;a++)
{
int p;
scanf("%d",&p);
if(p>l)
{
ans=ans+p-l;
}
l=p;
}
printf("%d\n",ans);
}

经过测试,此思路可以轻松拿下所有点,仅耗时33ms


题目详见:https://www.luogu.org/problemnew/show/P5019